package com.idealighter.game.recharge.manager;

import com.alibaba.fastjson.JSONObject;

import com.idealighter.game.recharge.struct.ValidationResult;
import com.idealighter.utils.check.EmptyUtil;
import com.idealighter.utils.http.Http;
import com.idealighter.utils.json.JsonUtil;

import javax.ws.rs.core.MediaType;

public class AppleReceiptValidation {

  // verify reciept URLs
  public static final String TEST_VALIDATE_RECEIPT_URL =
      "https://sandbox.itunes.apple.com/verifyReceipt";
  public static final String PRODUCTION_VALIDATE_RECIEPT_URL =
      "https://buy.itunes.apple.com/verifyReceipt";

  private AppleReceiptValidation() {}

  /**
   * Validates . an Apple app store receipt to verify a purchase was made.
   * 
   * @see <a href=
   *      "https://developer.apple.com/library/ios/releasenotes/General/ValidateAppStoreReceipt/Chapters/ValidateRemotely.html#//apple_ref/doc/uid/TP40010573-CH104-SW1">Apple
   *      Developer - Validating Receipts With The App Store</a>
   * @param receipt a <code>String</code> containing the receipt data of the in app purchase
   * @param test a <code>boolean</code> to indicate whether the the validation process should use
   *        Apple's sandbox for testing
   * @return a Google Gson <code>JsonObject</code> containing the JSON returned from the API
   * @throws AppleReceiptValidationFailedException gets thrown when the response from the Apple API
   *         server responded in an unexpected way or the receipt is invalid
   */
  public static ValidationResult validateReciept(String receipt, boolean test) {
    JSONObject obj = new JSONObject();
    obj.put("receipt-data", receipt);

    // get the URL to use
    String validationUrl = test ? TEST_VALIDATE_RECEIPT_URL : PRODUCTION_VALIDATE_RECIEPT_URL;

    String responseContent = Http.post(validationUrl).contentType(MediaType.APPLICATION_JSON)
        .body(obj.toString()).request();

    ValidationResult result = null;
    if (EmptyUtil.stringIsNotEmpty(responseContent)) {
      result = JsonUtil.fromJson(responseContent, ValidationResult.class);
      int status = result.getStatus();
      if (status != 0) {
        if (status == 21003) {
          throw new AppleReceiptValidationFailedException(
              "Couldn't validate the receipt because the Apple API server returned "
                  + "[Status 21003: The receipt could not be authenticated.]");
        } else if (status == 21000) {
          throw new AppleReceiptValidationFailedException(
              "Couldn't validate the receipt because the Apple API server returned "
                  + "[Status 21000: The App Store could not read the JSON object you provided]");
        } else if (status == 21002) {
          throw new AppleReceiptValidationFailedException(
              "Couldn't validate the receipt because the Apple API server returned "
                  + "[Status 21002: "
                  + "The data in the receipt-data property was malformed or missing]");
        } else if (status == 21005) {
          throw new AppleReceiptValidationFailedException(
              "Couldn't validate the receipt because the Apple API server returned "
                  + "[Status 21005: " + "The receipt server is not currently available]");
        } else if (status == 21007) {
          throw new AppleReceiptValidationFailedException(
              "Couldn't validate the receipt because the Apple API server returned "
                  + "[Status 21007: "
                  + "This receipt is from the test environment, but it was sent to "
                  + "the production environment for verification. "
                  + "Send it to the test environment instead]");
        } else if (status == 21008) {
          throw new AppleReceiptValidationFailedException(
              "Couldn't validate the receipt because the Apple API server returned "
                  + "[Status 21008: " + "This receipt is from the production environment, "
                  + "but it was sent to the test environment for verification. "
                  + "Send it to the production environment instead]");
        }
        result = null;
      }
    }
    return result;
  }

  public static class AppleReceiptValidationFailedException extends RuntimeException {
    private static final long serialVersionUID = 1L;

    public AppleReceiptValidationFailedException() {
      super();
    }

    public AppleReceiptValidationFailedException(String message) {
      super(message);
    }

    public AppleReceiptValidationFailedException(String message, Throwable cause) {
      super(message, cause);
    }

    public AppleReceiptValidationFailedException(Throwable cause) {
      super(cause);
    }
  }

}
